package com.dgut.courses_selecting_sys.controller;

import com.alibaba.fastjson.JSON;
import com.dgut.courses_selecting_sys.constants.RabbitMqKey;
import com.dgut.courses_selecting_sys.constants.RedisKey;
import com.dgut.courses_selecting_sys.entity.AjaxResult;
import com.dgut.courses_selecting_sys.utils.RedisUtil;
import com.dgut.courses_selecting_sys.utils.ShiroUtils;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import static com.dgut.courses_selecting_sys.constants.RedisKey.USER_CHOOSE_COURSE_ID;

@Slf4j
@Controller
@RequestMapping("/test")
public class TestController {

    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    RabbitTemplate rabbitTemplate;

    Random random1 = new Random(10000);
    /**
     * 高并发测试
     */
    @ResponseBody
    @GetMapping("/chooseCourse")
    public AjaxResult chooseCourse(long courseId) {
        String keyNameForCount = RedisKey.COURSE_COUNT + courseId;
        Integer count = (Integer) redisUtil.get(keyNameForCount);
        if (count == null || count <= 0) {
            return AjaxResult.error("课程人数已被选满！");
        }
        RLock rLock = redissonClient.getLock(keyNameForCount);
        try {
            rLock.tryLock(10, TimeUnit.SECONDS);
            Integer count2 = (Integer) redisUtil.get(keyNameForCount);
            if (count2 == null || count2 <= 0) {
                return AjaxResult.error("课程人数已被选满！");
            } else {
                redisUtil.decr(keyNameForCount, 1L);
                Map<String, Long> map = new HashMap();
                map.put("userId",  random1.nextLong()+1);
                map.put("courseId", courseId);
                rabbitTemplate.convertAndSend("TEST_MQ", JSON.toJSONString(map));
                return AjaxResult.success("课程选择成功！请留意邮件通知");
            }
        } catch (InterruptedException e) {
            //当redis中没有键的消息，则课程开选结束ttl过期，或者未开选和不存在该课程！
            return AjaxResult.error("课程不可选或未开选！");
        } finally {
            if(rLock.isLocked()){ // 是否还是锁定状态
                if(rLock.isHeldByCurrentThread()){ // 当前执行线程的锁
                    rLock.unlock(); // 释放锁
                }
            }
        }
    }
}
